package com.ithuameng.admin.app.system.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ithuameng.admin.app.system.model.Role;
import com.ithuameng.admin.app.system.model.User;
import com.ithuameng.admin.app.system.model.admin.qo.RoleQo;
import com.ithuameng.admin.app.system.model.admin.qo.RoleUserQo;
import com.ithuameng.admin.app.system.model.admin.vo.RoleSaveVo;
import com.ithuameng.admin.app.system.model.admin.vo.RoleUpdateStatusVo;
import com.ithuameng.admin.app.system.model.admin.vo.RoleUpdateVo;
import com.ithuameng.admin.app.system.model.vo.AdminPageResVo;
import com.ithuameng.admin.app.system.model.vo.R;
import com.ithuameng.admin.app.system.service.IRoleService;
import com.ithuameng.admin.app.system.service.IUserRoleService;
import com.ithuameng.admin.app.system.service.IUserService;
import com.ithuameng.admin.enums.CommonError;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色控制器
 *
 * @author ithuameng
 */
@Api(tags = "角色控制器")
@RestController
@RequestMapping("/admin/v1/role")
public class RoleController extends AdminBaseController {

    @Resource
    private IUserService userService;

    @Resource
    private IRoleService roleService;

    @Resource
    private IUserRoleService userRoleService;

    @ApiOperation("获取角色列表")
    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping("/list")
    public R<AdminPageResVo<Role>> list(RoleQo roleQo) {
        Page<Role> page = new Page<>(roleQo.getPageNumber(), roleQo.getPageSize());
        IPage<Role> pageList = roleService.listRole(page, roleQo);
        AdminPageResVo<Role> rolePage = new AdminPageResVo<>();
        rolePage.setRecords(pageList.getRecords());
        rolePage.setPage(pageList.getPages());
        rolePage.setTotal(pageList.getTotal());
        return new R<>(rolePage);
    }

    @ApiOperation("获取所有角色列表(不含ADMIN)")
    @GetMapping("/normal/all/list")
    public R<List<Role>> listAll() {
        List<Role> roles = roleService.list().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList());
        return new R<>(roles);
    }

    @ApiOperation("根据角色编号获取详细信息")
    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping(value = "/detail/{id}")
    public R<Role> getInfo(@PathVariable Long id) {
        roleService.checkRoleDataScope(id);
        Role role = roleService.getById(id);
        return new R<>(role);
    }

    @ApiOperation("新增角色")
    @PreAuthorize("@ss.hasPermi('system:role:add')")
    @PostMapping(value = "/add")
    public R<Boolean> add(@Validated @RequestBody RoleSaveVo roleSaveVo) {
        Role role = new Role();
        BeanUtils.copyProperties(roleSaveVo, role);
        if (!roleService.checkRoleNameUnique(role.getName(), null)) {
            return new R<>(CommonError.BIZ_ERR, "角色名称已存在");
        }
        if (!roleService.checkRoleKeyUnique(role.getRoleKey(), null)) {
            return new R<>(CommonError.BIZ_ERR, "权限字符已存在");
        }
        if (roleSaveVo.getStatus() == null) {
            return new R<>(CommonError.BIZ_ERR, "请选择状态");
        }
        roleService.saveRoleWithMenus(role, roleSaveVo.getMenuIds());
        return new R<>(CommonError.OK, "添加成功");
    }

    @ApiOperation("修改保存角色")
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @PostMapping(value = "/edit")
    public R<Boolean> edit(@Validated @RequestBody RoleUpdateVo roleUpdateVo) {
        Role role = new Role();
        BeanUtils.copyProperties(roleUpdateVo, role);
        if (!roleService.checkRoleNameUnique(role.getName(), role.getId())) {
            return new R<>(CommonError.BIZ_ERR, "角色名称已存在");
        }
        if (!roleService.checkRoleKeyUnique(role.getRoleKey(), role.getId())) {
            return new R<>(CommonError.BIZ_ERR, "权限字符已存在");
        }
        if (roleUpdateVo.getStatus() == null) {
            return new R<>(CommonError.BIZ_ERR, "请选择状态");
        }
        roleService.updateRoleWithMenus(role, roleUpdateVo.getMenuIds());
        return new R<>(CommonError.OK, "更新成功");
    }

    @ApiOperation("状态修改")
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @PostMapping("/changeStatus")
    public R<Boolean> changeStatus(@Validated @RequestBody RoleUpdateStatusVo roleUpdateStatusVo) {
        if (Role.ADMIN_ID.equals(roleUpdateStatusVo.getRoleId())) {
            return new R<>(CommonError.BAD_REQUEST, "超级管理员角色状态不能修改");
        }
        if (roleUpdateStatusVo.getStatus() == null) {
            return new R<>(CommonError.BIZ_ERR, "请选择状态");
        }
        roleService.updateRoleStatus(roleUpdateStatusVo.getRoleId(), roleUpdateStatusVo.getStatus());
        return new R<>(CommonError.OK, "状态更新成功");
    }

    @ApiOperation("删除角色")
    @PreAuthorize("@ss.hasPermi('system:role:remove')")
    @PostMapping("/delete/{roleIds}")
    public R<Boolean> remove(@PathVariable Long[] roleIds) {
        if (roleIds == null) {
            return new R<>(CommonError.BAD_REQUEST, "未选择角色");
        }
        if (ArrayUtils.contains(roleIds, Role.ADMIN_ID)) {
            return new R<>(CommonError.BAD_REQUEST, "超级管理员角色不能删除");
        }
        roleService.deleteRoleByIds(roleIds);
        return new R<>(CommonError.OK, "删除成功");
    }

    @ApiOperation("查询已分配用户角色列表")
    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping("/authUser/allocatedList")
    public R<AdminPageResVo<User>> allocatedList(RoleUserQo roleUserQo) {
        Page<User> page = new Page<>(roleUserQo.getPageNumber(), roleUserQo.getPageSize());
        IPage<User> pageList = userService.selectAllocatedList(page, roleUserQo);
        AdminPageResVo<User> userPage = new AdminPageResVo<>();
        userPage.setRecords(pageList.getRecords());
        userPage.setPage(pageList.getPages());
        userPage.setTotal(pageList.getTotal());
        return new R<>(userPage);
    }

    @ApiOperation("查询未分配用户角色列表")
    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping("/authUser/unallocatedList")
    public R<AdminPageResVo<User>> unallocatedList(RoleUserQo roleUserQo) {
        Page<User> page = new Page<>(roleUserQo.getPageNumber(), roleUserQo.getPageSize());
        IPage<User> pageList = userService.selectUnallocatedList(page, roleUserQo);
        AdminPageResVo<User> userPage = new AdminPageResVo<>();
        userPage.setRecords(pageList.getRecords());
        userPage.setPage(pageList.getPages());
        userPage.setTotal(pageList.getTotal());
        return new R<>(userPage);
    }

    @ApiOperation("批量选择用户授权")
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @PostMapping("/authUser/selectAll")
    public R<Boolean> selectAuthUserAll(Long roleId, Long[] userIds) {
        if (roleId == null) {
            return new R<>(CommonError.BIZ_ERR, "角色不能为空");
        }
        if (userIds == null || userIds.length == 0) {
            return new R<>(CommonError.BIZ_ERR, "请至少选择一个用户");
        }
        userRoleService.assignRole2User(roleId, userIds);
        return new R<>(CommonError.OK, "操作成功");
    }

    @ApiOperation("取消授权用户")
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @PostMapping("/authUser/cancel")
    public R<Boolean> cancelAuthUser(Long roleId, Long userId) {
        if (roleId == null) {
            return new R<>(CommonError.BIZ_ERR, "角色不能为空");
        }
        if (userId == null) {
            return new R<>(CommonError.BIZ_ERR, "用户不能为空 ");
        }
        userRoleService.removeRoleByUserId(roleId, userId);
        return new R<>(CommonError.OK, "操作成功");
    }

    @ApiOperation("批量取消授权用户")
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @PostMapping("/authUser/cancelAll")
    public R<Boolean> cancelAuthUserAll(Long roleId, Long[] userIds) {
        if (roleId == null) {
            return new R<>(CommonError.BIZ_ERR, "角色不能为空");
        }
        if (userIds == null || userIds.length == 0) {
            return new R<>(CommonError.BIZ_ERR, "请至少选择一个用户");
        }
        userRoleService.removeRoleByUserId(roleId, userIds);
        return new R<>(CommonError.OK, "操作成功");
    }
}
